/**
 * @description: 场景方法-需要传入场景对象
 * @file: function.ts
 * @author: Evan
 * @date: 2025.07.17 10:45:44
 * @week: 周四
 * @version: V
 */

import { Scene } from '../class'

type ST = InstanceType<typeof Scene>

import { modelOpts } from './store'
import * as MD from '../data/methods'
import { Message } from '@/utils/element'
import { request } from '@/api'
const { THREE, Utils, Hooks } = MD

const { materialReplace, exportGlb, getAnimations } = Hooks.useMaterial()

export function main(core: ST) {
  return {
    add() {
      const gui = core.gui
      if (!core.container) return
      // @ts-ignore
      const fileEl = core.container.parentNode.querySelector(
        'input[type="file"]'
      ) as HTMLInputElement

      const option = {
        importFile: () => {
          fileEl.click()
        },
        resetTree: () => {
          if (!core.modelGroup) return
          const list = MD.modelConvertTree(core.modelGroup)
          modelOpts.uploadList = list
        },
        exportGltf: () => {
          this.export(false)
        },
        exportGlb: () => {
          this.export()
        },
        exportPoints: () => {
          const dotText = [core.setPiece].map(el => {
            let p = <any>el.position
            return `{ "x": ${p.x.toFixed(2) * 1}, "y": ${p.y.toFixed(2) * 1}, "z": ${
              p.z.toFixed(2) * 1
            } }`
          })
          modelOpts.dotText = dotText.join(',')
          core.copyTextarea('坐标复制成功！')
        },
        target: () => {
          if (!core.controls) return
          const vs = core.controls.target
          modelOpts.dotText = `{ x: ${vs.x}, y: ${vs.y}, z: ${vs.z} }`
          core.copyTextarea('中心点复制成功！')
        },
        camera: () => {
          const vs = core.camera.position
          modelOpts.dotText = `{ x: ${vs.x}, y: ${vs.y}, z: ${vs.z} }`
          core.copyTextarea('相机坐标复制成功！')
        },
        clearScene: () => {
          this.clearScene()
        }
      }

      const group = gui.addFolder('主功能')
      group.add(option, 'importFile').name('上传文件(fbx、glb、gltf、ldr、mpd)')
      group.add(option, 'resetTree').name('模型树结构重置')
      group.add(option, 'exportGltf').name('导出 .gltf')
      group.add(option, 'exportGlb').name('导出 .glb')
      group.add(option, 'exportPoints').name('导出坐标')
      group.add(option, 'target').name('中心点')
      group.add(option, 'camera').name('相机坐标')
      group.add(option, 'clearScene').name('清空场景')
      group.open()
    },

    // 添加模型组
    addModelGroup() {
      const group = new THREE.Group()
      group.name = '模型组'
      core.addObject(group)
      core.modelGroup = group

      const help = new THREE.Group()
      help.name = '辅助组'
      core.helperGroup = help
      core.addObject(help)
    },

    // 添加模型
    addModel(obj: MD.THREE.Object3D) {
      if (core.modelGroup) {
        core.modelGroup.add(obj)
        const list = MD.modelConvertTree(core.modelGroup)
        modelOpts.uploadList = list
        if (typeof core.extend.addGroupCall === 'function') core.extend.addGroupCall(list)
      }
    },

    // 添加辅助
    addHelper(obj: MD.THREE.Object3D) {
      if (core.helperGroup) {
        core.helperGroup.add(obj)
      }
    },
    // 是否上传过模型
    judgeUploadModel() {
      const list = core.modelGroup?.children || []
      if (list.length == 0) {
        Message('未上传模型！', 'error')
        return false
      }
      return true
    },

    // 删除模型
    deleteModel(e: { uuid: string }) {
      const obj = core.modelGroup?.getObjectByProperty('uuid', e.uuid)
      if (!obj) {
        return Message('对象不存在，请重置树结构！', 'error')
      }

      // 控制目标则移除
      if (obj == core.transformControls?.object) {
        core.transformControls?.detach()
      }
      obj.parent?.remove(obj)
      obj.clear()
      Message('删除成功！')
    },

    // 选中模型
    selectModel(e: { uuid: string }) {
      const obj = core.modelGroup?.getObjectByProperty('uuid', e.uuid)
      if (!obj) return
      core.helperGroup?.children.forEach((el: any) => {
        if (el.type === 'BoxHelper') {
          core.disposeObj(el)
          core.helperGroup?.remove(el)
        }
      })
      core.modules.tsControls?.setObject(obj)

      modelOpts.uuid = e.uuid

      // 创建 BoxHelper
      var boxHelper = new THREE.BoxHelper(obj, 0xf00f00)
      //更新
      boxHelper.update()
      this.addHelper(boxHelper)
    },

    // 上传模型
    uploadedModel(obj: MD.THREE.Object3D, filename: string) {
      if (!obj) return
      obj.userData.__upload_model__ = true

      if (core.modelGroup) {
        const find = core.modelGroup.children.find(it => it.name === filename) as any
        core.disposeObj(find)
        core.modelGroup.remove(find)
      }

      const s = core.guiOpts.scale
      const group = new THREE.Group()
      obj.traverse((el: AnyObject) => {
        if (el.isSpotLight || el.isPointLight) {
          if (el.isSpotLight) {
            group.add(el.target)
          }
        }
        materialReplace(group, core.guiOpts, el)
      })

      if (group.children.length) {
        this.addHelper(group)
      }

      // @ts-ignore
      if (!obj.isMesh) {
        obj.name = filename
      }

      let model = Utils.modelDeepClone(obj)
      const list = Utils.findObjectsByHasProperty(model.children, ['true'], 'isSkinnedMesh')

      if (list.length) {
        model = obj
      }

      console.log(model)
      const p = model.position
      modelOpts.dotText = `模型初始坐标: {
      "x": ${p.x},
      "y": ${p.y},
      "z": ${p.z}
    }`

      const scale = model.scale
      model.scale.set(s * scale.x, s * scale.y, s * scale.z)
      model.animations = obj.animations
      this.addModel(model)

      // 相机动画
      if (core.guiOpts.insetAnimate) {
        core.cameraViewReset()
      }

      // 动画
      if (obj.animations.length) {
        let mixer = new THREE.AnimationMixer(model)
        const names: string[] = []
        const action = obj.animations.reduce((ob: AnyObject, cur: any) => {
          const key = cur.name || ''
          names.push(key)
          ob[key] = mixer.clipAction(cur)
          ob[key].timeScale = 1
          return ob
        }, {})
        action[names[0]].play()

        model.userData.__action_names__ = names
        model.userData.__action__ = action
        model.userData.__mixer__ = mixer
      }
      console.log(core)

      // 上传接口提醒
      request.uploadModel()
    },

    // 导出
    export(isGlb?: boolean) {
      const list = core.modelGroup?.children || []
      if (!this.judgeUploadModel()) return
      const isOne = list.length == 1
      const model: any = isOne ? list[0] : core.modelGroup
      const animations = getAnimations(model)
      exportGlb(model, animations, isOne ? model.name : '综合场景', isGlb)
    },

    // 清空场景
    clearScene() {
      if (core.text) {
        core.scene.remove(core.text)
      }
      if (core.water) {
        core.scene.remove(core.water)
      }

      core.disposeObj(core.modelGroup)
      core.disposeObj(core.helperGroup)
      this.addModelGroup()

      core.transformControls?.detach()
      modelOpts.dotText = ''
      modelOpts.uploadList = []
      modelOpts.uuid = ''
    }
  }
}
